; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S < %s -passes=memcpyopt -verify-memoryssa | FileCheck %s

; Array

define void @array_zero(ptr %p) {
; CHECK-LABEL: @array_zero(
; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 1 [[P:%.*]], i8 undef, i64 0, i1 false)
; CHECK-NEXT:    ret void
;
  store [0 x i8] zeroinitializer, ptr %p
  ret void
}

define void @array_nonzero(ptr %p) {
; CHECK-LABEL: @array_nonzero(
; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 1 [[P:%.*]], i8 0, i64 1, i1 false)
; CHECK-NEXT:    ret void
;
  store [1 x i8] zeroinitializer, ptr %p
  ret void
}

; Structure

define void @struct_zero(ptr %p) {
; CHECK-LABEL: @struct_zero(
; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 1 [[P:%.*]], i8 undef, i64 0, i1 false)
; CHECK-NEXT:    ret void
;
  store { } zeroinitializer, ptr %p
  ret void
}
define void @struct_nonzero(ptr %p) {
; CHECK-LABEL: @struct_nonzero(
; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 1 [[P:%.*]], i8 0, i64 1, i1 false)
; CHECK-NEXT:    ret void
;
  store { i8 } zeroinitializer, ptr %p
  ret void
}

; Vector

; Test only non-zero vector. Zero element vector is illegal

define void @vector_fixed_length_nonzero(ptr %p) {
; CHECK-LABEL: @vector_fixed_length_nonzero(
; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr <16 x i8>, ptr [[P]], i64 1
; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 16 [[P:%.*]], i8 0, i64 32, i1 false)
; CHECK-NEXT:    ret void
;
  store <16 x i8> zeroinitializer, ptr %p
  %tmp1 = getelementptr <16 x i8>, ptr %p, i64 1
  store <16 x i8> zeroinitializer, ptr %tmp1
  ret void
}

define void @vector_scalable_nonzero(ptr %p) {
; CHECK-LABEL: @vector_scalable_nonzero(
; CHECK-NEXT:    store <vscale x 4 x i32> zeroinitializer, ptr [[P:%.*]], align 16
; CHECK-NEXT:    ret void
;
  store <vscale x 4 x i32> zeroinitializer, ptr %p
  ret void
}
